<template>
  <ul>
    <li v-for="(item, index) in treeData" :key="index">
      <span :class="{arrowTransform: item.expand, arrow: true}"
            @click="handleExpand(item)"
            v-show="item.children && item.children.length"></span>
      <input type="checkbox" v-model="item.checked" @change="handleCheck(item)" />
      <span :class="{selected: item.selected}" @click="handleSelect(item)">{{item.label}}</span>
      <transition name="fade">
        <tree-menu v-show="item.expand"
                      :tree-data="item.children"
                      :flat-tree="flatTree">
        </tree-menu>
      </transition>
    </li>
  </ul>
</template>
<script>
  import Bus from "@/components/common/bus"; //引入公共媒介JS BUS
  export default {
    name:'tree-menu',
    props: ["treeData", "flatTree"],
    data() {
      return {

      }
    },
    created: function () {

    },
    methods: {
      //展开或收起
      handleExpand(item) {
        var expand = item.expand,
          nodeKey = item.nodeKey;
        var node = this.flatTree[nodeKey].node;
        this.$set(node, "expand", !expand);
      },
      //节点选中
      handleSelect(item) {
        var nodeKey = item.nodeKey;
        var node = this.flatTree[nodeKey].node;
        var currentSelectedKey = this.flatTree.findIndex(obj => {
          return obj.node.selected;
        });
        //每次只能选择一个
        if (currentSelectedKey >= 0 && currentSelectedKey != item.nodeKey) {
          this.$set(this.flatTree[currentSelectedKey].node, 'selected', false);
        }
        this.$set(node, 'selected', !node.selected);
        this.getSelectNodes();
      },
      //节点勾选
      handleCheck(item) {
        var checked = item.checked,
          nodeKey = item.nodeKey;
        var node = this.flatTree[nodeKey].node;
        this.$set(node, 'checked', checked);
        this.updateTreeUp(nodeKey);
        this.updateTreeDown(node, { checked: checked });
        this.getCheckedNodes();
      },
      //判断当前勾选节点的父节点是否需要勾选
      updateTreeUp(nodeKey) {
        var parentKey = this.flatTree[nodeKey].parent;
        var childrenKey = "children";
        if (typeof parentKey == 'undefined') return;

        var node = this.flatTree[nodeKey].node;
        var parent = this.flatTree[parentKey].node;
        if (node.checked == parent.checked) return;

        if (node.checked == true) {
          this.$set(parent, 'checked', parent[childrenKey].every(function (node) {
            return node.checked;
          }));
        } else {
          this.$set(parent, 'checked', false);
        }
        this.updateTreeUp(parentKey);
      },
      //判断当前勾选节点的子节点是否勾选
      updateTreeDown(node) {
        var changes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
        var childrenKey = "children";

        for (var key in changes) {
          this.$set(node, key, changes[key]);
        }
        if (node[childrenKey]) {
          node[childrenKey].forEach(function (child) {
            this.updateTreeDown(child, changes);
          }.bind(this));
        }
      },
      //获取已勾选节点
      getCheckedNodes() {
        var arr = this.flatTree.filter(item => {
          return item.node.checked;
        }).map(item => {
          return item.node;
          });
        Bus.$emit("checkedNodes", arr)
        //console.log(arr)
      },
      //获取已选中节点
      getSelectNodes() {
        var arr = this.flatTree.filter(item => {
          return item.node.selected;
        }).map(item => {
          return item.node;
        });
        //console.log(arr)
      }
    },

}
</script>
<style scoped>
  * {
    margin: 0;
    padding: 0;
  }

  li {
    list-style: none;
    padding: 5px 0;
    padding-left:20px;
  }

  .arrow {
    position: relative;
    width: 0;
    height: 0;
    border-width: 6px 0 6px 6px;
    border-style: solid;
    border-color: transparent transparent transparent #999;
    cursor: pointer;
    display: inline-block;
    transition: transform .3s;
  }

  .arrowTransform {
    transform: rotate(90deg);
  }

  .selected {
    /*background: #2b85e4;*/
  }
  @media screen and (max-width: 576px){
    li{
      padding-left: 5px;
    }
  }
</style>
